package cn.sfa.common.utils;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Random;

import net.sf.json.JSONArray;

/**
 * 
* 类名称：CommonUtil   
* 类描述： 一般通用工具类
* 创建人：lenovo   
* 创建时间：2011-12-13 下午09:39:07      
* @version v1.0
 */
public class CommonUtil {
	/**
	 * 判断传入对象是否为空或值为空
	 *
	 * @param obj 需要判断是否为空的对象
	 * @return true-如果对象为空，false-如果对象非空
	 */
	public static boolean isEmpty(Object obj) {
		// 判断是否为空
		if (obj == null)
			return true;
		// ----------------根据各种对象类型判断是否值为空--------------
		if (obj instanceof String)
			return ((String) obj).trim().equals("");
		if (obj instanceof Collection) {
			Collection coll = (Collection) obj;
			return coll.size() == 0;
		}
		if (obj instanceof Map) {
			Map map = (Map) obj;
			return map.size() == 0;
		}
		if (obj.getClass().isArray())
			return Array.getLength(obj) == 0;
		else
			return false;
	}

	/**
	 * 组织html业务，显示值，供自定义标签用
	 *
	 * @param value 源字符串
	 * @param len 需要显示的源字符串长度
	 * @return 按 len 长度截取后的字符串
	 */
	public static String showValue(String value, int len) {
		// 判断是否为空
		if (isEmpty(value))
			return "&nbsp;";
		// 根据长度取值，并构建html语句
		if (value.length() <= len) {
			return value;
		} else {
			StringBuffer buf = new StringBuffer((new StringBuilder(
					"<span title='")).append(value).append("'>").toString());
			buf.append(value.substring(0, len));
			buf.append("...</span>");
			return buf.toString();
		}
	}

	/**
	 * 产生时间形式的uuid方法+后4位随机数
	 *
	 * @return 时间形式的uuid + 后4位随机数组成的字符串
	 */
	public static String getUUID() {
		// 定义uuid
		String uuId = "0";
		// 定义时间格式
		SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String tempId = sf.format(new Date());
		// 构造uuid
		if (Long.parseLong(uuId) >= Long.parseLong(tempId))
			uuId = (new StringBuilder(String.valueOf(Long.parseLong(uuId) + 1L)))
					.toString();
		else
			uuId = tempId;

		// 返回
		return uuId + get4RandomNum();
	}

	/**
	 * 检查传入值是否为null并处理方法，null则转为空值，否则为其身
	 *
	 * @param s 
	 *            为字符串类
	 * @return 等传入参数为 null 时返回 "" ,否则返回源字符串本身
	 */
	public static String jugeAndFixNull(String s) {
		// 判断s是否为null，是则返回空串
		if (s == null) {
			return "";
		} else {// 否则返回其自身
			return s;
		}
	}

	/**
	 * 将一个字符串数组转换为long数组，by weiqiang.yang
	 *
	 * @param strArr 字符串数组
	 * @return 长整形数组
	 */
	public static Long[] strArrToLongArr(String[] strArr) {
		Long[] retArr = new Long[strArr.length];
		for (int i = 0; i < strArr.length; i++) {
			retArr[i] = Long.parseLong(strArr[i]);
		}
		return retArr;
	}

	/**
	 * 生成4位随机数
	 *
	 * @return 4位随机数
	 */
	public static String get4RandomNum() {
		Random random = new Random();
		String randomNum = "" + random.nextInt(9) + random.nextInt(9)
				+ random.nextInt(9) + random.nextInt(9);
		return randomNum;
	}

	/**
	 * 得到对象的JSON字符串
	 *
	 * @param object 一个对象
	 * @return 一个JSON字符串
	 */
	public static String getJSONString(Object object) {
		return new JSONArray().fromObject(object).toString();
	}
	
	
	/**
	  * 格式化一个字符串，以带 HTML 下划线格式返回。例如：
	  *
	  * @param str 字符串
	  * @param size 每行字节数
	  * @return
	  */
	 public static String getUnderLineString(String str, int size) {
	  // 可变字符序列，用于保存返回结果
	  StringBuffer sb = new StringBuffer();
	  try {
	   // 如果要格式化的字符串为空，则付给它一个空格
	   if (str == null || str.equals("")) str = " ";
	   // 根据没用字节数计算显示的总行数
	   int totalLine = (str.getBytes("GBK").length + size - 1) / size;
	   // 截取字符串的开始位置、结束位置，字符串的字符数量，字符的字节数
	   int start, stop, byteLen, charLen, wordByteLen;
	   // 字符
	   String word;
	   // 加下划线开始标签
	   sb.append("<u>");
	   // 逐行处理
	   for (int line = 0; line < totalLine; line++) {
	    // 每一行开始，它们的值都初始为 0
	    start = stop = byteLen = wordByteLen = 0;
	    charLen = str.length();
	    // 计算 stop 与 byteLen 的值
	    while (byteLen <= size && stop < charLen) {
	     word = str.substring(stop, stop + 1);
	     wordByteLen = word.getBytes("GBK").length;
	     byteLen += wordByteLen;
	     stop++;
	    }
	    // 如果字节数等于每行字节数，并且结尾字符的位置刚好是字符串的字符数量，则stop的值是正确的；
	    // 否则表明在上面的循环中自加多了一次，需要自减一次才是正确数值。
	    stop = (byteLen <= size && stop == charLen) ? stop : --stop;
	    // 截取本行中的字符串并添加到结果字符序列中
	    sb.append(str.substring(start, stop));
	    // 同理，如果字节数比每行字节数大是不合理的，需要减去最后一次循环自增的"字符字节数"
	    byteLen = byteLen <= size ? byteLen : byteLen - wordByteLen;
	    // 字节数未够每行字节数的，以空格补上
	    while (byteLen++ < size) {
	     sb.append(" ");
	    }
	    // 加换行
	    sb.append("<br/>");
	    // 去掉已处理的，开始后面未处理的
	    str = str.substring(stop);
	   }
	   // 加下划线结束标签
	   sb.append("</u>");
	  } catch (UnsupportedEncodingException e) {
	   // 捕捉 getBytes("GBK")的异常
	   // e.printStackTrace();
	   sb.append("<u>");
	   for (int i = 0; i < size; i++) {
	    sb.append(" ");
	   }
	   sb.append("</u>");
	  }
	  // 替换空格为 HTML 格式并返回
	  return sb.toString().replaceAll(" ", "&nbsp;");
	 }
	 
	 /**
	  * 格式化一个字符串，以带 HTML 下划线格式返回（默认长度30个字节）。例如：
	  *
	  * @param str 字符串
	  * @return
	  */
	 public static String getUnderLineString(String str) {
	  return getUnderLineString(str, 30);
	 }
	 
	 
	/**
	 * 
	 * @Title: divide
	 * @author: LiXiang
	 * @Description: 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指 定精度，以后的数字四舍五入
	 * @param v1
	 *            被除数
	 * @param v2
	 *            除数
	 * @param scale
	 *            精确度
	 * @return 两个参数的商
	 * @throws
	 */
	public static double divide(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("The scale must be integer or zero");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}
	
	
	/**
	 * 提供精确的加法运算。
	 * 
	 * @author: LiXiang
	 * @param v1
	 *            被加数
	 * @param v2
	 *            加数
	 * @return 两个参数的和
	 */

	public static double add(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.add(b2).doubleValue();
	}
}
